package com.xqboss.common.utils;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * 事务处理类
 *
 * @author mujiangchuan
 * @date 2020/10/26
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class TransactionalManage {

    private final TransactionTemplate transactionTemplate;

    /**
     * 事务管理
     *
     * @param consumer 需要被事务处理的代码块
     * @return true-业务逻辑执行成功,false-务逻辑执行失败
     */
    @SuppressWarnings("all")
    public boolean execute(Consumer consumer) {
        return transactionTemplate.execute(transactionStatus -> {
            try {
                boolean isRollback = consumer.accept();
                if (!isRollback) {
                    transactionStatus.setRollbackOnly();
                    return false;
                }
                return true;
            } catch (Exception e) {
                log.warn("事务管理,业务逻辑发生异常", e);
                transactionStatus.setRollbackOnly();
                return false;
            }
        });
    }

    /**
     * 事务管理
     *
     * @param consumer 需要被事务处理的代码块
     * @return true-业务逻辑执行成功,false-务逻辑执行失败
     */
    @SuppressWarnings("all")
    public boolean executeWithException(Consumer consumer) throws Exception {
        return transactionTemplate.execute(transactionStatus -> {
            try {
                boolean isRollback = consumer.accept();
                if (!isRollback) {
                    transactionStatus.setRollbackOnly();
                    return false;
                }
                return true;
            } catch (Exception e) {
                log.warn("事务管理,业务逻辑发生异常", e);
                transactionStatus.setRollbackOnly();
                throw e;
            }
        });
    }

    /**
     * 事务管理
     *
     * @param consumer 需要被事务处理的代码块
     * @return true-业务逻辑执行成功,false-务逻辑执行失败
     */
    @SuppressWarnings("all")
    public boolean executeWithException(Consumer consumer, ExceptionRunner exceptionRunner) throws Exception {
        try{
            return transactionTemplate.execute(transactionStatus -> {
                try {
                    boolean isRollback = consumer.accept();
                    if (!isRollback) {
                        transactionStatus.setRollbackOnly();
                        return false;
                    }
                    return true;
                } catch (Exception e) {
                    log.warn("事务管理,业务逻辑发生异常", e);
                    transactionStatus.setRollbackOnly();
                    throw e;
                }
            });
        }catch (Exception e){
            exceptionRunner.run(e);
            throw e;
        }
    }

    public interface ExceptionRunner {
        void run(Exception e);
    }
}
